home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / Talking Telnet / source / FTPserver / macutil.c < prev    next >
Text File  |  1996-06-22  |  7KB  |  241 lines

  1. /*  MACUTIL.C
  2. *****************************************************************
  3. *    NCSA Telnet for the Macintosh                                *
  4. *                                                                *
  5. *    National Center for Supercomputing Applications                *
  6. *    Software Development Group                                    *
  7. *    152 Computing Applications Building                            *
  8. *    605 E. Springfield Ave.                                        *
  9. *    Champaign, IL  61820                                        *
  10. *                                                                *
  11. *    Copyright (c) 1986-1993,                                    *
  12. *    Board of Trustees of the University of Illinois                *
  13. *****************************************************************
  14. *    April, 1993    Entirely rewritten by Jim Browne to use HFS.
  15. */
  16.  
  17. #ifdef MPW
  18. #pragma segment FTPServer
  19. #endif
  20.  
  21.  
  22. #include "maclook.proto.h"
  23. #include "telneterrors.h"
  24. #include "DlogUtils.proto.h"
  25. #include "macutil.proto.h"
  26.  
  27.  
  28. /* Some globals for file lookup */
  29. char FileName[256];
  30.  
  31. //    Get the name of the directory identified by vRefNum & dirID
  32. //    (works for volumes too... [dirID = 2])
  33. void GetDirectoryName(short vRefNum, long dirID, Str32 name)
  34. {
  35.     CInfoPBRec    theInfo;
  36.     
  37.     WriteZero((Ptr)&theInfo, sizeof(CInfoPBRec));
  38.     theInfo.dirInfo.ioVRefNum = vRefNum;
  39.     theInfo.dirInfo.ioDrDirID = dirID;
  40.     theInfo.dirInfo.ioNamePtr = name;
  41.     theInfo.dirInfo.ioFDirIndex = -1;        // Only give me the Directory Info
  42.     PBGetCatInfoSync(&theInfo);
  43. }
  44.  
  45. //    Convert the given volume name to a reference number.  Returns the default vRefNum
  46. //    if the volume specified is not found.
  47. short VolumeNameToRefNum(Str32 volumeName)
  48. {
  49.     short    retval;
  50.     
  51.     if (SetVol(volumeName, 0) != noErr) return(-1);
  52.     GetVol(NULL, &retval);
  53.     
  54.     return(retval);
  55. }
  56.     
  57. void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
  58. {
  59.     CInfoPBRec    block;
  60.     Str255        directoryName;
  61.     OSErr        err;
  62.  
  63.     fullPathName[0] = '\0';
  64.  
  65.     block.dirInfo.ioDrParID = dirID;
  66.     block.dirInfo.ioNamePtr = directoryName;
  67.     do {
  68.             block.dirInfo.ioVRefNum = vRefNum;
  69.             block.dirInfo.ioFDirIndex = -1;
  70.             block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
  71.             if ((err = PBGetCatInfoSync(&block)) != noErr) return;
  72.             pstrcat(directoryName, (StringPtr)"\p/");
  73.             pstrinsert(fullPathName, directoryName);
  74.     } while (block.dirInfo.ioDrDirID != 2);
  75.  
  76.     pstrinsert(fullPathName, "\p/");
  77. }
  78.  
  79. //    ChangeDirectory will change the directory relative from the provided dirID and 
  80. //        vRefNum.  It handles preceding ".." modifiers as well as absolute pathnames.
  81. short ChangeDirectory(long *dirID, short *vRefNum,char *pathname)
  82. {
  83.     CInfoPBRec        theDirInfo;
  84.     char        tempst[256], *nSlash, *start;
  85.     short         NumberOfLevelsToGoUp = 0, temp, localvRefNum;
  86.     long        junk1, junk2, localdirID;
  87.     OSErr        err;
  88.     
  89.     start = pathname;
  90.     localvRefNum = *vRefNum;
  91.     localdirID = *dirID;
  92.     
  93.     while ( (nSlash = strchr(pathname,'/') ) !=0L) {
  94.         if (( (nSlash - pathname) == 2) && (*pathname=='.') && (*(pathname+1) =='.') ) {
  95.             pathname += 3L;
  96.             start = pathname;
  97.             NumberOfLevelsToGoUp++;
  98.             }
  99.         else {
  100.             *nSlash=':';
  101.             pathname=nSlash + 1L;
  102.             }
  103.         }
  104.     
  105.     if ( strcmp("..",pathname)==0) {
  106.         start[0]=0;
  107.         NumberOfLevelsToGoUp++;
  108.         }
  109.  
  110.     // Now start points to the beginning of a relative pathname devoid of ".."'s, and colons
  111.     //        for seperators rather than slashes.
  112.     
  113.     if ( *start==':') {                            // This is a fully qualified pathname
  114.         if (NumberOfLevelsToGoUp) return(1);    // Someone did a "../..//blah"...
  115.         nSlash = strchr(start+1L, ':');            // Seperate out volume name
  116.         if (strlen(start) == 1)                    // Someone did a "cd /"
  117.             localdirID = 2;                        //        Use top level directory
  118.         else {
  119.             if (nSlash != NULL) *nSlash = 0;
  120.             strcpy(tempst, start+1);            // Remove leading colon
  121.             strcat(tempst, ":");                // Add trailing colon
  122.             CtoPstr(tempst);
  123.             SetVol((StringPtr)tempst, 0);
  124.             GetVol(NULL, &temp);
  125.             GetWDInfo(temp, &localvRefNum, &junk1, &junk2);
  126.             localdirID = 2;
  127.  
  128.             if (nSlash != NULL) {                // There's more than a volume name
  129.                 *nSlash = ':';                    // Restore the leading slash
  130.                 strcpy( tempst, nSlash);
  131.                 CtoPstr(tempst);                // tempst now contains relative pathname
  132.                 
  133.                 WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec));
  134.                 theDirInfo.dirInfo.ioVRefNum = localvRefNum;        // Now find the directory on the volume
  135.                 theDirInfo.dirInfo.ioDrDirID = localdirID;
  136.                 theDirInfo.dirInfo.ioNamePtr = (StringPtr)tempst;
  137.                 theDirInfo.dirInfo.ioFDirIndex = 0;
  138.                 if ((err = PBGetCatInfo(&theDirInfo, FALSE)) != noErr) return(1);
  139.                 localdirID = theDirInfo.dirInfo.ioDrDirID;
  140.                 }        
  141.             }
  142.         }
  143.     else
  144.         {    // This is a relative pathname, start by taking care of any ".."s...
  145.             WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec));
  146.             while (NumberOfLevelsToGoUp && (localdirID != 2)) {
  147.                 theDirInfo.dirInfo.ioVRefNum = localvRefNum;
  148.                 theDirInfo.dirInfo.ioDrDirID = localdirID;
  149.                 theDirInfo.dirInfo.ioNamePtr = 0;
  150.                 theDirInfo.dirInfo.ioFDirIndex = -1;
  151.                 if ((err = PBGetCatInfo(&theDirInfo, FALSE)) != noErr) return(1);
  152.                 localdirID = theDirInfo.dirInfo.ioDrParID;
  153.                 NumberOfLevelsToGoUp--;
  154.                 }
  155.         
  156.             // Now use the relative pathname to find out the actual directory ID
  157.             // Relative pathnames must begin with a colon, so put on on the beginning
  158.             
  159.             if(start[0]) {
  160.                 strcpy(tempst+1, start);
  161.                 tempst[0] = ':';
  162.                 CtoPstr(tempst);
  163.                 WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec));
  164.                 theDirInfo.dirInfo.ioVRefNum = localvRefNum;
  165.                 theDirInfo.dirInfo.ioDrDirID = localdirID;
  166.                 theDirInfo.dirInfo.ioNamePtr = (StringPtr)tempst;
  167.                 theDirInfo.dirInfo.ioFDirIndex = 0;
  168.                 if ((err = PBGetCatInfo(&theDirInfo, FALSE)) != noErr) return(1);
  169.                 localdirID = theDirInfo.dirInfo.ioDrDirID;
  170.                 }
  171.         }
  172.     
  173.     *dirID = localdirID;        // Everything went ok, change the dirID and vRefNum
  174.     *vRefNum = localvRefNum;        
  175.     return(0);
  176. }
  177.  
  178. short wccheck(char *file, char *template)    /* BYU - routine now returns (short) for recursion. */
  179. {
  180.     while(*template) {
  181.         if (*template=='*') {
  182.             template++;
  183.             if (*template) {
  184.                 while((*file) && !wccheck(file,template)) file++;    /* BYU */
  185.                 if ((*file)==0) return(0);
  186.                 }
  187.             else return(1);
  188.             continue;
  189.             }
  190.         else
  191.             if ((*template!='?') && (*template!=*file)) return(0);
  192.         template++;file++;
  193.         }
  194.     if (*file)            /* BYU */
  195.         return(0);        /* BYU */
  196.     else                /* BYU */
  197.         return(1);        /* BYU */
  198. }
  199.  
  200. /* getFileName
  201. *  find the name in the given directory which matches the wildcard
  202. *  specification    */
  203. char *getFileName(char *spec, CInfoPBRec *finfo)
  204. {
  205.     CInfoPBRec *localfinfo;
  206.     Boolean done = FALSE;
  207.     localfinfo = (CInfoPBRec *) myNewPtr(sizeof(CInfoPBRec));    
  208.     
  209.     finfo->hFileInfo.ioNamePtr=(StringPtr) FileName;
  210.     
  211.     while (!done)
  212.     {
  213.         BlockMove(finfo, localfinfo, sizeof(CInfoPBRec));
  214.         if (PBGetCatInfo(localfinfo,FALSE)!=0) {
  215.             DisposePtr((Ptr)localfinfo);
  216.             return(0L);
  217.             }
  218.     
  219.         FileName[FileName[0]+1]=0;
  220.         if ((!wccheck(&FileName[1],spec))|| //it doesnt match
  221.             (((localfinfo->hFileInfo.ioFlAttrib & 0x10)&& //its an invisible directory
  222.             (localfinfo->dirInfo.ioDrUsrWds.frFlags & (fInvisible | 0x1000)))||
  223.             (!(localfinfo->hFileInfo.ioFlAttrib & 0x10)&&//its an invisible file
  224.             (localfinfo->hFileInfo.ioFlFndrInfo.fdFlags)&(fInvisible | 0x1000))))
  225.  
  226.             finfo->hFileInfo.ioFDirIndex++; //go to next one
  227.         else    
  228.             done = TRUE;
  229.         }
  230.  
  231.     if (localfinfo->hFileInfo.ioFlAttrib & 0x10) //its a directory
  232.     {
  233.         FileName[++FileName[0]]='/';
  234.         FileName[FileName[0]+1]=0;
  235.     }
  236.  
  237.     DisposePtr((Ptr)localfinfo);
  238.     return(&FileName[1]);
  239. }
  240.  
  241.